﻿
using System.ComponentModel.Design;
using Microsoft.EntityFrameworkCore;
using StudentManagementSystem.DatabaseConn;
using StudentManagementSystem.Dtos;
using StudentManagementSystem.Entities;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;

namespace StudentManagementSystem.Services
{
    public class CompanyRepository : ICompanyRepository
    {
        private readonly MysqlDbContext _context;

        public CompanyRepository(MysqlDbContext context)
        {
            _context = context ?? throw new ArgumentNullException(nameof(context));
        }

        public async Task<IEnumerable<Company>> GetCompaniesAsync(CompanyDtoParameters parameter)
        {
            if (parameter == null)
                throw new ArgumentNullException(nameof(parameter));

            if (string.IsNullOrWhiteSpace(parameter.CompanyName) && string.IsNullOrWhiteSpace(parameter.SearchTerm))
            {
                return await _context.Companies
                    .ToListAsync();
            }
            var queryExpression = _context.Companies as IQueryable<Company>;
            if (!string.IsNullOrWhiteSpace(parameter.CompanyName))
            {
                parameter.CompanyName = parameter.CompanyName.Trim();
                queryExpression.Where(x => x.Name == parameter.CompanyName);
            }
            if (!string.IsNullOrWhiteSpace(parameter.SearchTerm))
            {
                parameter.SearchTerm = parameter.SearchTerm.Trim();
                queryExpression.Where(x => x.Name.Contains(parameter.SearchTerm)
                                          || x.Introduction.Contains(parameter.SearchTerm)
                );
            }
            return await queryExpression.ToListAsync();
        }

        public async Task<Company> GetCompanyAsync(Guid companyId)
        {
            if (companyId == Guid.Empty)
            {
                throw new ArgumentNullException(nameof(companyId));
            }
            return await _context.Companies
                .FirstOrDefaultAsync(x => x.Id == companyId);
        }

        public async Task<IEnumerable<Company>>
            GetCompaniesAsync(IEnumerable<Guid> companyIds)
        {
            if (companyIds == null)
            {
                throw new ArgumentNullException(nameof(companyIds));
            }
            return await _context.Companies
                .Where(x => companyIds.Contains(x.Id))
                .OrderBy(x => x.Name)
                .ToListAsync();
        }

        public void AddCompany(Company company)
        {
            if (company == null)
            {
                throw new ArgumentNullException(nameof(company));
            }
            company.Id = Guid.NewGuid();
            if (company.Employees != null)
            {
                foreach (var employ in company.Employees)
                {
                    employ.Id = Guid.NewGuid();
                }
            }
            _context.Companies.Add(company);
        }

        public void UpdateCompany(Company company)
        {
            if (company == null)
            {
                throw new ArgumentNullException(nameof(company));
            }
            _context.Companies.Update(company);

            //_context.Entry(company).State = EntityState.Modified;
        }

        public void DeleteCompany(Company company)
        {
            if (company == null)
            {
                throw new ArgumentNullException(nameof(company));
            }
            _context.Companies.Remove(company);
        }

        public async Task<bool> CompanyExistsAsync(Guid companyId)
        {
            if (companyId == Guid.Empty)
            {
                throw new ArgumentNullException(nameof(companyId));
            }
            return await _context.Companies
                .AnyAsync(c => c.Id == companyId);
        }

        public async Task<IEnumerable<Employee>> GetEmployeesAsync(Guid companyId, string genderDisplay, string q)
        {
            if (companyId == Guid.Empty)
            {
                throw new ArgumentNullException(nameof(companyId));
            }
            if (string.IsNullOrWhiteSpace(genderDisplay) && string.IsNullOrWhiteSpace(q))
            {
                return await _context.Employees
                .Where(e => e.CompanyId == companyId)
                .OrderBy(x => x.EmployeeNo)
                .ToListAsync();
            }
            var items = _context.Employees.Where(x => x.CompanyId == companyId);
            if (!string.IsNullOrWhiteSpace(genderDisplay))
            {
                genderDisplay = genderDisplay.Trim();
                var genderTrans = Enum.Parse<Gender>(genderDisplay);
                items = items.Where(x => x.Gender == genderTrans);

            }
            if (!string.IsNullOrWhiteSpace(q))
            {
                q = q.Trim();
                items = items
                    .Where(x => x.EmployeeNo.Contains(q)
                    || x.FirstName.Contains(q)
                    || x.LastName.Contains(q));
            }
            return await items
                .OrderBy(x => x.EmployeeNo)
                .ToListAsync();
        }

        public async Task<Employee> GetEmployeeAsync(Guid companyId, Guid employeeId)
        {
            if (companyId == Guid.Empty)
            {
                throw new ArgumentNullException(nameof(companyId));
            }
            if (employeeId == Guid.Empty)
            {
                throw new ArgumentNullException(nameof(employeeId));
            }
            /*return await _context.Employees
                .FirstOrDefaultAsync(e =>
                    e.CompanyId == companyId &&
                    e.Id == employeeId);*/
            return await _context.Employees
                .Where(e =>
                    e.CompanyId == companyId &&
                    e.Id == employeeId)
                .FirstOrDefaultAsync();
        }

        public void AddEmployee(Guid companyId, Employee employee)
        {
            if (companyId == Guid.Empty)
            {
                throw new ArgumentNullException(nameof(companyId));
            }
            if (employee == null)
            {
                throw new ArgumentNullException(nameof(employee));
            }
            // 确保员工关联到指定公司
            employee.CompanyId = companyId;
            _context.Employees.Add(employee);
        }

        public void UpdateEmployee(Employee employee)
        {
            //_context.Entry(company).State = EntityState.Modified;
        }

        public void DeleteEmployee(Employee employee)
        {
            if (employee == null)
            {
                throw new ArgumentNullException(nameof(employee));
            }
            _context.Employees.Remove(employee);
        }

        public async Task<bool> SaveAsync()
        {
            return await _context.SaveChangesAsync() > 0;
        }
    }
}
